#include "BlockQueue.hpp"
#include "Thread.hpp"
#include <string>
#include <vector>
#include <unistd.h>
#include <ctime>

using namespace ThreadTest;

void Consumer(BlockQueue<int> &bq)
{
    while (true)
    {
        int data;
        bq.Pop(&data);
        std::cout << "Consumer Consum data is " << data << std::endl;
        sleep(2);
    }
}

void Productor(BlockQueue<int> &bq)
{
    int cnt = 1;
    while (true)
    {
        bq.Excute(cnt);
        std::cout << "Productor produce data is " << cnt++ << std::endl;
    }
}

void StartComn(std::vector<Thread<BlockQueue<int>>>* threads, int num, BlockQueue<int>& bq, func_t<BlockQueue<int>> func)
{
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread-" + to_string(i + 1);
        threads->emplace_back(func, bq, name);
        threads->back().Start();
    }
}

void StartProductor(std::vector<Thread<BlockQueue<int>>>* threads, int num, BlockQueue<int>& bq)
{
    StartComn(threads, num, bq, Consumer);
}

void StartConsumer(std::vector<Thread<BlockQueue<int>>>* threads, int num, BlockQueue<int>& bq)
{
    StartComn(threads, num, bq, Productor);
}

void WaitAllThread(std::vector<Thread<BlockQueue<int>>>* threads)
{
    for (auto thread : *threads)
    {
        thread.Join();
    }
}

int main()
{
    BlockQueue<int>* bq = new BlockQueue<int>(10);
    std::vector<Thread<BlockQueue<int>>> threads;
    StartProductor(&threads, 1, *bq);
    StartConsumer(&threads, 1, *bq);
    WaitAllThread(&threads);
    return 0;
}